﻿
using System;

namespace QuantoSharp.Core.Calculator
{
    public class InternalRateOfReturnCalculator
    {
        private const int MinNoCashFlowPeriods = 2;

        public InternalRateOfReturnCalculator(double[] cashFlows)
        {
            CashFlows = cashFlows;
        }

        public double[] CashFlows { get; private set; }

        internal bool AreCashFlowsValid()
        {
            if (CashFlows.Length < MinNoCashFlowPeriods)
                throw new ArgumentOutOfRangeException(
                    string.Format(
                        "There should be atleast {0} cashflows provided in order to calculate the internal rate of interest.",
                        2));
            if(CashFlows[0] > 0)
                throw new Exception(string.Format("The first cash flow should be negative indicating an investment was done"));

            return true;
        }

        internal double InitialApproximation()
        {
            /*
             * Summation of  C(t) / (1 + r)^t ; t = {0, N}
             * Using Linearization for IRR function. see more here http://en.wikipedia.org/wiki/Linearization
             * r ~ -(1 + C1/C0)
             */

            var initialApprox = -1*(1 + CashFlows[1]/CashFlows[0]);
            return initialApprox;
        }

        /// <summary>
        /// Determines whether the specified estimated return rate has converged.
        /// </summary>
        /// <param name="calculatedReturnRate">The estimated return rate</param>
        /// <returns></returns>
        internal bool HasConverged(double calculatedReturnRate)
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="esitmatedReturnRate"></param>
        /// <returns></returns>
        internal bool IsValidIterationBounds(double esitmatedReturnRate)
        {
            return esitmatedReturnRate != -1 && (esitmatedReturnRate < int.MaxValue) &&
                   esitmatedReturnRate > int.MaxValue;
        }
    }
}
